package com.flow.asyncflow.core.core;


import com.alibaba.fastjson.JSONObject;
import com.flow.asyncflow.core.annotation.FlowInfo;
import com.flow.asyncflow.core.entity.config.AsyncFlowConfigInfo;
import com.flow.asyncflow.core.entity.config.AsyncFlowInfo;
import com.flow.asyncflow.core.entity.core.*;
import com.flow.asyncflow.core.entity.sql.ExecuteSql;
import com.flow.asyncflow.core.enums.ExecuteEnum;
import com.flow.asyncflow.core.node.*;
import com.flow.asyncflow.core.utils.configuration.AsyncFlowConfiguration;
import com.flow.asyncflow.core.utils.log.asyncflowlog.AsyncFlowCommon_Log;
import com.flow.asyncflow.core.utils.log.businesslog.AsyncFlowBusinessLog;
import com.flow.asyncflow.core.utils.msg.AsyncFlowSendMsg;
import com.flow.asyncflow.core.utils.save.BaseSave;
import com.flow.asyncflow.core.utils.threadpool.ThreadPoolExecutorMain;
import com.mongodb.internal.connection.ConcurrentLinkedDeque;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.util.StopWatch;

import java.lang.annotation.Annotation;
import java.util.*;
import java.util.concurrent.*;


@SuppressWarnings("unchecked")
public abstract class AsyncFlowManager<TContext, TReqTypeEnum extends Enum<?>> implements CommandLineRunner {

    /**
     * 流节点集合【普通节点】--各个流内部定义
     */
    private final LinkedHashMap<ExecuteEnum, LinkedHashMap<IFlowNode, Boolean>> flowNodes = new LinkedHashMap<>();
    /**
     * 异步流流信息
     */
    private AsyncFlowInfo asyncFlowInfo = new AsyncFlowInfo();

    private static AsyncFlowConfigInfo asyncFlowStaticInfo = null;
    /**
     * 节点流线程池
     */
    private static ExecutorService pool = null;

    private static String testReqStr;

    private AsyncFlowBaseGetData asyncFlowBaseGetData = null;
    //region 初始化

    /**
     * 初始化
     */
    protected AsyncFlowManager() {
        //加载线程池
        if (pool == null) {
            pool = ThreadPoolExecutorMain.getCustomThreadPoolExecutor();

        }
        //加载站点配置信息（数据库、环境、报存地址）
        if (asyncFlowStaticInfo == null) {
            AsyncFlowConfiguration autoConfiguration = new AsyncFlowConfiguration();
            Map<String, String> dataBaseInfo = autoConfiguration.getDataBaseInfo();
            asyncFlowStaticInfo = new AsyncFlowConfigInfo();
            //for (Map.Entry<String, String> entry : dataBaseInfo.entrySet()) {
            //    asyncFlowStaticInfo.getDataBaseInfo().put(entry.getKey(), entry.getValue());
            //}
            asyncFlowStaticInfo.setDataBaseInfo(dataBaseInfo);
            asyncFlowStaticInfo.setEvn(autoConfiguration.getEvn());
            asyncFlowStaticInfo.setMongoDBConfigStr(autoConfiguration.getMongoDBConfigStr());
            asyncFlowStaticInfo.setMongoDBName(autoConfiguration.getMongoDBName());
            asyncFlowStaticInfo.setMongoDBTableName(autoConfiguration.getMongoDBTableName());
            asyncFlowStaticInfo.setNodeArmUrl(autoConfiguration.getNodeArmUrl());
            asyncFlowStaticInfo.setBusinessArmUrl(autoConfiguration.getBusinessArmUrl());
            asyncFlowStaticInfo.setBusinessLogUrl(autoConfiguration.getBusinessLogUrl());
        }
        //加载当前流信息，名称，负责人等
        if (StringUtils.isBlank(asyncFlowInfo.getFlowName())
                && StringUtils.isBlank(asyncFlowInfo.getFlowMaintainName())
                && asyncFlowInfo.getTimeOutsLimit() == 0) {
            Annotation[] flowInfo = this.getClass().getAnnotations();
            for (Annotation annotation : flowInfo) {
                //获取方法名
                if (annotation instanceof FlowInfo) {
                    asyncFlowInfo.setFlowName(((FlowInfo) annotation).flowName());
                    asyncFlowInfo.setFlowMaintainName(((FlowInfo) annotation).flowMaintainName());
                    asyncFlowInfo.setTimeOutsLimit(((FlowInfo) annotation).timeOutsLimit());
                    asyncFlowInfo.setIgnoreFlowLog(((FlowInfo) annotation).ignoreFlowLog());
                    break;
                }
            }
            //for (Map.Entry<String, String> entry : asyncFlowStaticInfo.getDataBaseInfo().entrySet()) {
            //    asyncFlowInfo.getDataBaseInfo().put(entry.getKey(), entry.getValue());
            //}
            asyncFlowInfo.setDataBaseInfo(asyncFlowStaticInfo.getDataBaseInfo());
            asyncFlowInfo.setEvn(asyncFlowStaticInfo.getEvn());
            asyncFlowInfo.setMongoDBConfigStr(asyncFlowStaticInfo.getMongoDBConfigStr());
            asyncFlowInfo.setMongoDBName(asyncFlowStaticInfo.getMongoDBName());
            asyncFlowInfo.setMongoDBTableName(asyncFlowStaticInfo.getMongoDBTableName());
            asyncFlowInfo.setNodeArmUrl(asyncFlowStaticInfo.getNodeArmUrl());
            asyncFlowInfo.setBusinessArmUrl(asyncFlowStaticInfo.getBusinessArmUrl());
            asyncFlowInfo.setBusinessLogUrl(asyncFlowStaticInfo.getBusinessLogUrl());
        }
        //初始化记录上下文节点
        if (asyncFlowBaseGetData == null) {
            asyncFlowBaseGetData = new AsyncFlowBaseGetData();
        }
    }
    //endregion


    //region 添加节点到执行流中

    /**
     * 添加普通节点
     *
     * @param executeEnum 操作类型
     * @param flowNode    带具体类型的操作节点
     * @param isCanAsync  是否异步
     */
    protected void addFlowNode(ExecuteEnum executeEnum, IFlowNode flowNode, boolean isCanAsync) {

        LinkedHashMap<IFlowNode, Boolean> nodes = flowNodes.computeIfAbsent(executeEnum, k -> new LinkedHashMap<>());
        if (flowNode == null || nodes.containsKey(flowNode)) {
            return;
        }
        if (executeEnum == ExecuteEnum.Async) {
            isCanAsync = true;
        }
        nodes.put(flowNode, isCanAsync);
    }


    //endregion

    /**
     * 设置测试数据
     *
     * @param testStr 测试数据
     */
    protected void addTestStr(String testStr) {
        if (testReqStr == null) {
            testReqStr = testStr;
        }
    }

    //region 执行节点

    //region 执行节点【带耗时明细】

    /**
     * 执行节点【带耗时明细】
     *
     * @param executeEnum      操作类型
     * @param asyncFlowRequest 上下文
     * @param asyncFlowData    请求参数
     * @return AsyncFlowNodeResponse
     */
    private AsyncFlowNodeResponse exeNode(ExecuteEnum executeEnum, AsyncFlowRequest asyncFlowRequest, AsyncFlowContext asyncFlowData, LinkedHashMap<ExecuteEnum, Long> timeConsuming, AsyncFlowResponse response, boolean allNodeIsSuccess) {
        AsyncFlowNodeResponse asyncFlowNodeResponse;
        //如果是测试调用，对于验证和查询数据库，数据源直接跳过
        if (asyncFlowData.getAsyncFlowInfo().isTest() && (executeEnum == ExecuteEnum.Validator || executeEnum == ExecuteEnum.GetData || executeEnum == ExecuteEnum.GetDataPub)) {
            return new AsyncFlowNodeResponse(200, "成功");
        }
        if (executeEnum == ExecuteEnum.Async) {
            pool.execute(() -> {
                exeNode(ExecuteEnum.Async, asyncFlowRequest, asyncFlowData);
                AsyncFlowBusinessLog.saveBusinessLog(asyncFlowRequest, asyncFlowData, response.getMsg(), allNodeIsSuccess);
                //执行顺序 验证-->查询-->操作-->保存-->同步-->异步
                //当执行的操作是异步时，表示当前流所有的操作已经执行完成
                AsyncFlowCommon_Log.SaveExecuteTrackLogs(asyncFlowRequest, asyncFlowData, response, timeConsuming, allNodeIsSuccess, asyncFlowInfo);
            });

            return new AsyncFlowNodeResponse(200, "成功");
        }
        StopWatch sw = new StopWatch();
        sw.start(executeEnum.getMsg() + "-开始");
        asyncFlowNodeResponse = exeNode(executeEnum, asyncFlowRequest, asyncFlowData);
        sw.stop();
        long time = sw.getTotalTimeMillis();
        if (timeConsuming.containsKey(executeEnum)) {
            time = timeConsuming.get(executeEnum) + sw.getTotalTimeMillis();
        }
        timeConsuming.put(executeEnum, time);
        return asyncFlowNodeResponse;
    }


    //endregion

    //region 执行节点【基础执行】

    /**
     * 执行节点
     *
     * @param executeEnum      操作类型
     * @param asyncData        上下文
     * @param asyncFlowRequest 请求参数
     * @return AsyncFlowNodeResponse
     * @author lgq07612
     **/
    private AsyncFlowNodeResponse exeNode(ExecuteEnum executeEnum, AsyncFlowRequest asyncFlowRequest, AsyncFlowContext asyncData) {
        AsyncFlowNodeResponse asyncFlowNodeResponse = new AsyncFlowNodeResponse(200, "成功");
        List<FlowNodeTask> taskList = new ArrayList<>();
        LinkedHashMap<IFlowNode, Boolean> nodes = flowNodes.get(executeEnum);
        //执行查询时将公共查询一起执行
        if (executeEnum == ExecuteEnum.GetData) {
            LinkedHashMap<IFlowNode, Boolean> pubNodes = flowNodes.get(ExecuteEnum.GetDataPub);
            if (pubNodes != null && !pubNodes.isEmpty()) {
                if (nodes == null) {
                    nodes = new LinkedHashMap<>();
                }
                nodes.putAll(pubNodes);
            }
        }
        if (nodes == null || nodes.isEmpty()) {
            return asyncFlowNodeResponse;
        }
        for (Map.Entry<IFlowNode, Boolean> entry : nodes.entrySet()) {
            //需要异步执行
            if (entry.getValue() || executeEnum == ExecuteEnum.Async) {
                taskList.add(new FlowNodeTask(entry.getKey(), asyncFlowRequest, asyncData, entry.getValue(), asyncFlowInfo, executeEnum));
            } else {
                //异步执行集合里面还有未执行完成的任务
                asyncFlowNodeResponse = getTaskListFuture(executeEnum, asyncFlowRequest, taskList);
                if (asyncFlowNodeResponse.getCode() != 200 || asyncFlowNodeResponse.isBreakOff()) {
                    return asyncFlowNodeResponse;
                }
                taskList = new ArrayList<>();
                asyncFlowNodeResponse = new FlowNodeTask(entry.getKey(), asyncFlowRequest, asyncData, entry.getValue(), asyncFlowInfo, executeEnum).flowNodeTaskExecute();
                if (asyncFlowNodeResponse.getCode() != 200 || asyncFlowNodeResponse.isBreakOff()) {
                    return asyncFlowNodeResponse;
                }
            }
        }
        asyncFlowNodeResponse = getTaskListFuture(executeEnum, asyncFlowRequest, taskList);
        return asyncFlowNodeResponse;
    }

    //endregion

    //region 获取异步集合的结果

    /**
     * 获取异步集合的结果
     *
     * @param executeEnum 执行类型
     * @param taskList    集合
     * @return 节点返回
     */
    private AsyncFlowNodeResponse getTaskListFuture(ExecuteEnum executeEnum, AsyncFlowRequest asyncFlowRequest, List<FlowNodeTask> taskList) {
        AsyncFlowNodeResponse asyncFlowNodeResponse = new AsyncFlowNodeResponse(200, "成功");
        if (taskList == null || taskList.size() == 0) {
            return asyncFlowNodeResponse;
        }
        try {
            List<Future<AsyncFlowNodeResponse>> futureList = pool.invokeAll(taskList, 1000, TimeUnit.SECONDS);
            for (Future<AsyncFlowNodeResponse> future : futureList) {
                asyncFlowNodeResponse = future.get();
                //只有在非异步操作是需要跳出（异步操作之间互不影响，异步操作的失败，不影响后面的异步操作）
                if (executeEnum != ExecuteEnum.Async && (asyncFlowNodeResponse.getCode() != 200 || asyncFlowNodeResponse.isBreakOff())) {
                    return asyncFlowNodeResponse;
                }
            }

        } catch (InterruptedException | ExecutionException e) {
            String s = AsyncFlowSendMsg.buildErrorMsg(asyncFlowRequest, e, "获取异步集合的结果" + executeEnum.getMsg(), asyncFlowInfo);
            AsyncFlowSendMsg.sendQYWXMsg(asyncFlowInfo.getFlowMaintainName(), s, asyncFlowInfo.getNodeArmUrl());
        }
        return asyncFlowNodeResponse;
    }
    //endregion

    //endregion


    //region 本地测试时构建测试数据

    /**
     * 构建测试数据
     *
     * @param asyncFlowData 上下文
     */
    private void buildTestData(AsyncFlowContext asyncFlowData) {

        if (asyncFlowData.getAsyncFlowInfo().getEvn().equals("test") && StringUtils.isNotBlank(testReqStr)) {

            JSONObject add = JSONObject.parseObject(testReqStr);
            asyncFlowData.getDataSourceMap().putAll(add);
            asyncFlowData.getAsyncFlowInfo().setTest(true);

        }

    }
    //endregion

    //region 注入执行流、设置返回参数【子类重写】

    /**
     * 注入执行计划
     */
    protected abstract void managerStartup();


    //endregion

    //region 执行异步流【原始版本】

    ///**
    // * 执行异步流
    // *
    // * @param asyncFlowData 上下文
    // */
    //protected void exec(AsyncFlowRequest asyncFlowRequest, AsyncFlowPlusDataSlot asyncFlowData) {
    //    AsyncFlowPlusResponse asyncFlowPlusResponse = new AsyncFlowPlusResponse();
    //    AsyncFlowNodeResponse asyncFlowNodeResponse;
    //    boolean allNodeIsSuccess = false;
    //    //=======每个步骤（验证、查询、操作、保存、同步、异步）的耗时明细==============
    //    LinkedHashMap<ExecuteEnum, Long> timeConsuming = new LinkedHashMap<>();
    //    //=======每个步骤（验证、查询、操作、保存、同步、异步）的执行结果，默认是成功（200：成功，其他：失败）==============
    //    int validateCode, getDataCode = 200, operatorCode = 200, customSaveCode = 200, baseSaveCode = 200, syncCode = 200;
    //    String nodeErrorMsg = "";
    //    //======设置AsyncFlowRequest节点流的请求参数到上下文数据槽中==================
    //    asyncFlowData.setAsyncFlowRequest(asyncFlowRequest);
    //    asyncFlowData.setAsyncFlowInfo(asyncFlowInfo);
    //    asyncFlowData.setDataBaseInfo(asyncFlowStaticInfo.getDataBaseInfo());
    //    //================构建本地测试数据=============
    //    buildTestData(asyncFlowRequest, asyncFlowData);
    //    //================注入执行计划================
    //    managerStartup();
    //    //===================验证====================
    //    asyncFlowNodeResponse = exeNode(ExecuteEnum.Validator, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowPlusResponse, false);
    //    validateCode = asyncFlowNodeResponse.getCode();
    //    if (validateCode != 200) {
    //        //验证执行错误信息
    //        nodeErrorMsg = asyncFlowNodeResponse.getMsg();
    //    }
    //    //===================查询====================
    //    //table.get(ExecuteEnum.Validator,200)!=null--当前table中存在操作类型为 验证 执行结果为 200 的执行结果Msg
    //    if (validateCode == 200 && !asyncFlowNodeResponse.isBreakOff()) {
    //        asyncFlowNodeResponse = exeNode(ExecuteEnum.GetData, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowPlusResponse, false);
    //        getDataCode = asyncFlowNodeResponse.getCode();
    //        if (getDataCode != 200) {
    //            //验证执行错误信息
    //            nodeErrorMsg = asyncFlowNodeResponse.getMsg();
    //        }
    //        //===================操作====================
    //        if (getDataCode == 200) {
    //            asyncFlowNodeResponse = exeNode(ExecuteEnum.Operator, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowPlusResponse, false);
    //            operatorCode = asyncFlowNodeResponse.getCode();
    //            if (operatorCode != 200) {
    //                //操作执行错误信息
    //                nodeErrorMsg = asyncFlowNodeResponse.getMsg();
    //            }
    //            //===================保存====================
    //            if ((operatorCode == 200 && !asyncFlowNodeResponse.isBreakOff() && asyncFlowData.getExecuteSQLs().size() > 0) || asyncFlowData.getExecuteSQLs().stream().anyMatch(ExecuteSql::isMustExecute)) {
    //                asyncFlowNodeResponse = new BaseSave().execute(asyncFlowRequest, asyncFlowData, operatorCode, asyncFlowInfo, timeConsuming);
    //                baseSaveCode = asyncFlowNodeResponse.getCode();
    //                if (baseSaveCode != 200) {
    //                    //操作执行错误信息
    //                    nodeErrorMsg = StringUtils.isNotBlank(nodeErrorMsg) ? nodeErrorMsg + "|" + asyncFlowNodeResponse.getMsg() : asyncFlowNodeResponse.getMsg();
    //                }
    //                if (baseSaveCode == 200) {
    //                    asyncFlowNodeResponse = exeNode(ExecuteEnum.Save, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowPlusResponse, false);
    //                    customSaveCode = asyncFlowNodeResponse.getCode();
    //                    if (customSaveCode != 200) {
    //                        //操作执行错误信息
    //                        nodeErrorMsg = StringUtils.isNotBlank(nodeErrorMsg) ? nodeErrorMsg + "|" + asyncFlowNodeResponse.getMsg() : asyncFlowNodeResponse.getMsg();
    //                    }
    //                }
    //                //===================同步====================
    //                if (operatorCode == 200 && customSaveCode == 200 && baseSaveCode == 200) {
    //                    asyncFlowNodeResponse = exeNode(ExecuteEnum.Sync, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowPlusResponse, false);
    //                    syncCode = asyncFlowNodeResponse.getCode();
    //                    if (syncCode != 200) {
    //                        //操作执行错误信息
    //                        nodeErrorMsg = nodeErrorMsg + asyncFlowNodeResponse.getMsg() + "|";
    //                    }
    //                }
    //            }
    //        }
    //    }
    //    //=================设置异步流执行结果================
    //    asyncFlowPlusResponse.setCode(asyncFlowNodeResponse.getCode());
    //    if (validateCode == 200 && getDataCode == 200 && operatorCode == 200 && baseSaveCode == 200 && customSaveCode == 200 && syncCode == 200) {
    //        allNodeIsSuccess = true;
    //        asyncFlowPlusResponse.setMsg("成功");
    //    } else {
    //        asyncFlowPlusResponse.setMsg(nodeErrorMsg);
    //        if (validateCode == -1 || getDataCode == -1 || operatorCode == -1 || syncCode == -1 || baseSaveCode == -1 || customSaveCode == -1) {
    //            asyncFlowPlusResponse.setMsg("系统异常");
    //        }
    //    }
    //    //======设置AsyncFlowResponse节点流的返回参数到上下文数据槽中==================
    //    asyncFlowData.setAsyncFlowResponse(asyncFlowPlusResponse);
    //    //===================异步====================
    //    exeNode(ExecuteEnum.Async, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowPlusResponse, allNodeIsSuccess);
    //}
    //endregion


    //region 执行异步流


    /**
     * 执行异步流
     */
    public <TReq, TRes extends AsyncFlowResponse, TExeEnum extends TReqTypeEnum> TRes exec(TReq request, TExeEnum reqTypeEnum, Class<TRes> clazzRes, Class<TContext> clazzContext) {
        AsyncFlowRequest asyncFlowRequest = new AsyncFlowRequest();
        AsyncFlowResponse asyncFlowResponse = new AsyncFlowResponse();
        AsyncFlowContext asyncFlowData = new AsyncFlowContext();
        TRes response;
        AsyncFlowNodeResponse asyncFlowNodeResponse;
        boolean allNodeIsSuccess = false;
        //=======每个步骤（验证、查询、操作、保存、同步、异步）的耗时明细==============
        LinkedHashMap<ExecuteEnum, Long> timeConsuming = new LinkedHashMap<>();
        //=======每个步骤（验证、查询、操作、保存、同步、异步）的执行结果，默认是成功（200：成功，其他：失败）==============
        int validateCode = 200, getDataCode = 200, operatorCode = 200, customSaveCode = 200, baseSaveCode = 200, syncCode = 200;
        String nodeErrorMsg = "";
        //======构建上下文AsyncFlowPlusDataSlot和请求参数AsyncFlowRequest==================
        new AsyncFlowBaseValidator().buildAsyncFlowRequestAndContext(asyncFlowRequest, asyncFlowData, request, clazzRes, reqTypeEnum, clazzContext, asyncFlowInfo, timeConsuming);
        asyncFlowRequest = asyncFlowData.getAsyncFlowRequest(AsyncFlowRequest.class);
        response = asyncFlowData.getResponse(clazzRes);

        //================注入执行计划================
        ///managerStartup();
        //================构建本地测试数据=============
        buildTestData(asyncFlowData);
        //================记录上下文=============
        //在查下操作的最后添加一个记录上下文的 操作，当前操作只有在预发或者本地测试环境才会执行
        // recordContext(asyncFlowData);
        //===================验证====================
        asyncFlowNodeResponse = exeNode(ExecuteEnum.Validator, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
        validateCode = asyncFlowNodeResponse.getCode();
        //兼容老版本的写法，请求参数中父类AsyncFlowRequest的属性没有赋值
        //setRequestInfo(asyncFlowData, request);
        if (validateCode != 200) {
            //验证执行错误信息
            nodeErrorMsg = asyncFlowNodeResponse.getMsg();
        }
        //===================查询====================
        //table.get(ExecuteEnum.Validator,200)!=null--当前table中存在操作类型为 验证 执行结果为 200 的执行结果Msg
        if (validateCode == 200 && !asyncFlowNodeResponse.isBreakOff()) {
            asyncFlowNodeResponse = exeNode(ExecuteEnum.GetData, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
            getDataCode = asyncFlowNodeResponse.getCode();
            if (getDataCode != 200) {
                //验证执行错误信息
                nodeErrorMsg = asyncFlowNodeResponse.getMsg();
            }
            //===================操作====================
            if (getDataCode == 200) {
                asyncFlowNodeResponse = exeNode(ExecuteEnum.Operator, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
                operatorCode = asyncFlowNodeResponse.getCode();
                if (operatorCode != 200) {
                    //操作执行错误信息
                    nodeErrorMsg = asyncFlowNodeResponse.getMsg();
                }
                //===================保存====================
                if ((operatorCode == 200 && !asyncFlowNodeResponse.isBreakOff() && asyncFlowData.getExecuteSQLs().size() > 0) || asyncFlowData.getExecuteSQLs().stream().anyMatch(ExecuteSql::isMustExecute)) {
                    asyncFlowNodeResponse = new BaseSave().execute(asyncFlowRequest, asyncFlowData, operatorCode, asyncFlowInfo, timeConsuming);
                    baseSaveCode = asyncFlowNodeResponse.getCode();
                    if (baseSaveCode != 200) {
                        //操作执行错误信息
                        nodeErrorMsg = StringUtils.isNotBlank(nodeErrorMsg) ? nodeErrorMsg + "|" + asyncFlowNodeResponse.getMsg() : asyncFlowNodeResponse.getMsg();
                    }
                    if (baseSaveCode == 200) {
                        asyncFlowNodeResponse = exeNode(ExecuteEnum.Save, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
                        customSaveCode = asyncFlowNodeResponse.getCode();
                        if (customSaveCode != 200) {
                            //操作执行错误信息
                            nodeErrorMsg = StringUtils.isNotBlank(nodeErrorMsg) ? nodeErrorMsg + "|" + asyncFlowNodeResponse.getMsg() : asyncFlowNodeResponse.getMsg();
                        }
                    }
                    //===================同步====================
                    if (operatorCode == 200 && customSaveCode == 200 && baseSaveCode == 200) {
                        asyncFlowNodeResponse = exeNode(ExecuteEnum.Sync, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
                        syncCode = asyncFlowNodeResponse.getCode();
                        if (syncCode != 200) {
                            //操作执行错误信息
                            nodeErrorMsg = nodeErrorMsg + asyncFlowNodeResponse.getMsg() + "|";
                        }
                    }
                }
            }
        }
        //=================设置异步流执行结果================
        asyncFlowResponse.setCode(asyncFlowNodeResponse.getCode());
        if (validateCode == 200 && getDataCode == 200 && operatorCode == 200 && baseSaveCode == 200 && customSaveCode == 200 && syncCode == 200) {
            allNodeIsSuccess = true;
            asyncFlowResponse.setMsg("成功");
        } else {
            asyncFlowResponse.setMsg(nodeErrorMsg);
            if (validateCode == -1 || getDataCode == -1 || operatorCode == -1 || syncCode == -1 || baseSaveCode == -1 || customSaveCode == -1) {
                asyncFlowResponse.setMsg("系统异常");
            }
        }
        //======设置AsyncFlowResponse节点流的返回参数到上下文数据槽中、设置节点的返回==================
        asyncFlowData.setAsyncFlowResponse(asyncFlowResponse);
        //如果节点最终的执行接口不是成功的 将返回参数重置成初始值
        if (asyncFlowResponse.getCode() != 200) {
            try {
                response = clazzRes.newInstance();
            } catch (IllegalAccessException | InstantiationException ignored) {
            }
        }
        response.setMsg(asyncFlowResponse.getMsg());
        response.setCode(asyncFlowResponse.getCode());
        //===================异步====================
        //最后一步异步执行里面会记录请求参数，所以这边的asyncFlowRequest 用传入的接口参数
        exeNode(ExecuteEnum.Async, asyncFlowRequest, asyncFlowData, timeConsuming, response, allNodeIsSuccess);

        return response;
    }

    //region 记录上下文

    /**
     * 记录上下文
     *
     * @param asyncFlowData
     */
    private void recordContext(AsyncFlowContext asyncFlowData) {
        //在查下操作的最后添加一个记录上下文的 操作，当前操作只有在预发或者本地测试环境才会执行
        if (asyncFlowData.getAsyncFlowInfo().getEvn().equals("stage") || asyncFlowData.getAsyncFlowInfo().getEvn().equals("test")) {
            addFlowNode(ExecuteEnum.GetData, asyncFlowBaseGetData, false);
        }

    }

    //endregion

    /**
     * 初始化的时候注入节点
     *
     * @param asyncFlowInfo 流信息
     */
    private void injectNode(AsyncFlowInfo asyncFlowInfo) {
        managerStartup();
        //在查下操作的最后添加一个记录上下文的 操作，当前操作只有在预发或者本地测试环境才会执行
        if (asyncFlowInfo.getEvn().equals("stage") || asyncFlowInfo.getEvn().equals("test")) {
            addFlowNode(ExecuteEnum.GetData, asyncFlowBaseGetData, false);
        }
    }

    //endregion

    @Override
    public void run(String... args) {
        managerStartup();
        //在查下操作的最后添加一个记录上下文的 操作，当前操作只有在预发或者本地测试环境才会执行
        if (asyncFlowInfo.getEvn().equals("stage") || asyncFlowInfo.getEvn().equals("test")) {
            addFlowNode(ExecuteEnum.GetData, asyncFlowBaseGetData, false);
        }
    }
}
